﻿using AppSocketModel;
using BCGPSCommon;
using System;
using System.Collections.Generic;
using System.Text;

namespace AppSocketControl.GpsData.DataDispatch
{
    public class DispatchLocationReal
    {
        private readonly IRedisService redisService;

        public DispatchLocationReal()
        {
            redisService = new RedisService();
        }


        public void Run(string[] dataArr)
        {
            GpsInfoDto gpsInfoDto = Split(dataArr);
            if (gpsInfoDto != null)
            { 
                SaveRedis(gpsInfoDto);
            }

        }
        #region 分解数据
        private GpsInfoDto Split(string[] dataArr)
        {
            //推荐的定位信息
            if (dataArr[7].Contains("GNRMC"))
                return SplitGps(dataArr);
            if (dataArr[7].Contains("+CLBS:"))
                return SplitLbs(dataArr);
            if (dataArr[7].Contains("+LBS:"))
                return SplitLbs_WH_GM5(dataArr);

            return null;
        }

        private GpsInfoDto SplitGps(string[] dataArr)
        {
            //推荐的定位信息
            if (!dataArr[7].Contains("GNRMC"))
                return null;
             
            GpsInfoDto gpsInfoDto = new GpsInfoDto();
            gpsInfoDto.Imei = dataArr[5]; 
            string[] arrGps = dataArr[7].Split(',');
            if (arrGps.Length >= 13)
            {
                //有效数据
                if (arrGps[2] == "A")
                {
                    gpsInfoDto.GpsTime = new DateTime(
                        int.Parse(DateTime.Now.Year.ToString().Substring(0, 2) + arrGps[9].Substring(4, 2)),
                        int.Parse(arrGps[9].Substring(2, 2)),
                        int.Parse(arrGps[9].Substring(0, 2)),
                        int.Parse(arrGps[1].Substring(0, 2)),
                        int.Parse(arrGps[1].Substring(2, 2)),
                        int.Parse(arrGps[1].Substring(4, 2))).AddHours(8);
                    gpsInfoDto.SysTime = DateTime.Now;
                    gpsInfoDto.ServerTime = DateTime.Now;

                    var latArr = arrGps[3].Split('.');
                    if (latArr.Length == 2)
                    {
                        gpsInfoDto.Lat = int.Parse(latArr[0].Substring(0, 2)) + double.Parse(latArr[0].Substring(2, 2) + "." + latArr[1]) / 60.00;
                    }
                    else
                        return null;
                    gpsInfoDto.LatHemi = arrGps[4];

                    var lngArr = arrGps[5].Split('.');
                    if (lngArr.Length == 2)
                    {
                        gpsInfoDto.Lng = int.Parse(lngArr[0].Substring(0, 3)) + double.Parse(lngArr[0].Substring(3, 2) + "." + lngArr[1]) / 60.00;
                    }
                    else
                        return null;
                    gpsInfoDto.LngHemi = arrGps[6];

                    gpsInfoDto.Course = double.Parse(arrGps[8]);
                    gpsInfoDto.Speed = double.Parse(arrGps[7]);


                    if (dataArr[8].Contains("ADDINFO"))
                    {
                        GetAddInfo(dataArr[8].Split(','), ref gpsInfoDto);

                        if (gpsInfoDto == null)
                            return null;
                    }

                    return gpsInfoDto;
                }
            }
            return null;
        }

        private void GetAddInfo(string[] addInfoArr, ref GpsInfoDto gpsInfoDto)
        {
            foreach (var item in addInfoArr)
            {
                string[] innerInfoArr = item.Split(':');
                if (innerInfoArr.Length == 2)
                {
                    switch (innerInfoArr[0])
                    {
                        case "1":
                            switch (innerInfoArr[1])
                            {
                                case "GPS+BD":
                                    gpsInfoDto.Location = "GPS+北斗";
                                    break;
                                case "BD":
                                    gpsInfoDto.Location = "北斗";
                                    break;
                                case "GPS":
                                    gpsInfoDto.Location = "GPS";
                                    break;
                                case "LBS":
                                    gpsInfoDto.Location = "LBS";
                                    break;
                                default:
                                    gpsInfoDto.Location = innerInfoArr[1];
                                    break;
                            }
                            break;
                        case "2":
                            try
                            {
                                gpsInfoDto.BatteryVoltage = float.Parse(innerInfoArr[1]);
                            }
                            catch
                            {
                                gpsInfoDto = null;
                                return;
                            }
                            break;
                        case "3":
                            gpsInfoDto.WakeUpType = innerInfoArr[1];
                            break;
                        case "4":
                            gpsInfoDto.SendNo = int.Parse(innerInfoArr[1]);
                            break;

                    }
                }
            }
        }

        private GpsInfoDto SplitLbs(string[] dataArr)
        {
            GpsInfoDto gpsInfoDto = new GpsInfoDto();
            gpsInfoDto.Imei = dataArr[5];
            gpsInfoDto.SysTime = MongoDBDateTime.GetNowUtc();
            gpsInfoDto.ServerTime = MongoDBDateTime.GetNowUtc();
            gpsInfoDto.GpsTime = BCGPSCommon.MongoDBDateTime.GetNowUtc();

            string[] arrGps = dataArr[7].Split(',');
            Msg.WirteLine("arrGps.Length:=" + arrGps.Length, 5);
            foreach (var item in arrGps)
            {
                Msg.WirteLine(item, 10);
            }
            if (arrGps.Length >= 4)
            {
                if (arrGps[0].Contains("+CLBS:"))
                {
                    gpsInfoDto.Lng = double.Parse(arrGps[1]);
                    gpsInfoDto.Lat = double.Parse(arrGps[2]);
                    gpsInfoDto.Location = "LBS";

                    return gpsInfoDto;
                }
            }
            return null;
        }

        private GpsInfoDto SplitLbs_WH_GM5(string[] dataArr)
        {
            GpsInfoDto gpsInfoDto = new GpsInfoDto();
            gpsInfoDto.Imei = dataArr[5];
            gpsInfoDto.SysTime = DateTimeTransfrom.GetDateTime(dataArr[11]);
            gpsInfoDto.ServerTime = DateTime.Now;
            gpsInfoDto.GpsTime = BCGPSCommon.MongoDBDateTime.GetNowUtc();


            string[] arrGps = dataArr[7].Replace("+LBS:", "").Split(',');
            Msg.WirteLine("arrGps.Length:=" + arrGps.Length, 5);
            foreach (var item in arrGps)
            {
                Msg.WirteLine(item, 10);
            }
            if (arrGps.Length >= 3)
            {
                gpsInfoDto.Lng = double.Parse(arrGps[0].Replace("LNG = ", ""));
                gpsInfoDto.Lat = double.Parse(arrGps[1].Replace("LAT = ", ""));
                gpsInfoDto.Location = "LBS";

                return gpsInfoDto;
            } 
            return null;
        }
        #endregion



        //更新内存GPS位置字典
        private void SaveRedis(GpsInfoDto gpsInfoDto)
        {
            Console.WriteLine($"In Real Location Save Redis imei : {gpsInfoDto.Imei} ,  time:={gpsInfoDto.GpsTime}");
            var RedisOldLocation = redisService.Get<LocationDto>(GeneralContainer.RedisNameSpaceIMEILocation + gpsInfoDto.Imei);
 
            var locationDto = gpsInfoDto.GetLocationDto();
 
            if (RedisOldLocation != null && RedisOldLocation.PreAlarmDateTime !=null)
                locationDto.PreAlarmDateTime = RedisOldLocation.PreAlarmDateTime;
 
            redisService.AddAsync(GeneralContainer.RedisNameSpaceIMEILocation + gpsInfoDto.Imei, locationDto);
        } 
    }
}
